<template>
    <div class="drag-component-wrapper">
        <div class="drag-component-box">
            <div class="header" v-Drag>
                <slot name="header" />
            </div>
            <div class="content">
                <slot name="content" />
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, Directive, DirectiveBinding, watch, nextTick } from "vue";
const dragRef = ref<any>(null);
const props = defineProps({
    // 是否显示
    visible: {
        type: Boolean,
        default: false,
    },
    // 是否停止拖动
    stopDrag: {
        type: Boolean,
        default: false,
    },
});
const vDrag: Directive = {
    created() {},
    beforeMount() {},
    mounted(el: HTMLElement, dir: DirectiveBinding, vNode, preVNode) {
        const oDiv = el; // 当前元素
        // const minTop = oDiv.getAttribute("drag-min-top");
        const minTop = 0; // 离top最小距离，可做边界判断
        oDiv.onmousedown = (e) => {
            if (props.stopDrag) {
                return;
            }
            let target = oDiv;
            while (
                window.getComputedStyle(target).position !== "absolute" &&
                target !== document.body
            ) {
                target = target.parentElement as HTMLElement;
            }
            document.onselectstart = () => {
                return false;
            };
            // 鼠标按下，计算当前元素距离可视区的距离
            const disX = e.clientX - target.offsetLeft;
            const disY = e.clientY - target.offsetTop;
            document.onmousemove = (e) => {
                // 通过事件委托，计算移动的距离
                // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
                const l = e.clientX - disX;
                const t = e.clientY - disY;
                const { marginTop: mt, marginLeft: ml } =
                    window.getComputedStyle(target);
                // 计算移动当前元素的位置，并且给该元素样式中的left和top值赋值
                target.style.left = l - parseInt(ml) + "px";
                target.style.top =
                    (t < minTop ? minTop : t) - parseInt(mt) + "px";
            };
            document.onmouseup = (e) => {
                document.onmousemove = null;
                document.onmouseup = null;
                document.onselectstart = null;
            };
            // return false不加的话可能导致黏连，拖到一个地方时div粘在鼠标上不下来，相当于onmouseup失效
            return false;
        };
    },
    beforeUnmount() {},
    unmounted() {},
};

// watch(
//     () => props.visible,
//     (val) => {
//         console.log(props.visible);
//         console.log(props.stopDrag, "stopDrag");
//         if (val) {
//             nextTick(() => {
//                 // createContainer();
//                 const el = document.getElementById("dragId");
//                 // document.getElementById("app")?.appendChild(el);
//             });
//         } else {
//             // dragRef.value.remove();
//             // document.getElementById("dragId")?.remove();
//         }
//     }
// );
</script>

<style lang="scss" scoped>
.drag-component-wrapper {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 99999999 !important;
    pointer-events: none;
    overflow: hidden;
}
.drag-component-box {
    min-width: 200px;
    min-height: 200px;
    position: absolute;
    z-index: inherit;
    pointer-events: all;
    .header {
        width: 100%;
        height: 50px;
        background-color: aquamarine;
    }
    .content {
        height: 150px;
        background-color: bisque;
    }
}
</style>
